package com.helloworld.demo.atomic;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

public class AdderTest {
    public static void main(String[] args) {
        atomicLongVsLongAdder(10,10000);
        System.out.println("---------------------------------");
        atomicLongVsLongAdder(10,200000);
        System.out.println("---------------------------------");
        atomicLongVsLongAdder(100,200000);
        System.out.println("---------------------------------");
    }

    static void atomicLongVsLongAdder(int threadCount,int times){

        try {
            long start = System.currentTimeMillis();
            testLongAdder(threadCount,times);
            long end = System.currentTimeMillis();
            System.out.println("条件：线程个数"+threadCount + ",单线程计算次数："+times);
            System.out.println("结果：LongAdder方式增加计数："+ (threadCount * times) +"用时：" + (end - start));



            long start2 = System.currentTimeMillis();
            testAtomicLong(threadCount,times);
            long end2 = System.currentTimeMillis();
            System.out.println("条件：线程个数"+threadCount + ",单线程计算次数："+times);
            System.out.println("结果：AtomicLong方式增加计数："+ (threadCount * times) +"用时：" + (end2 - start2));

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static void testAtomicLong(int threadCount,int times) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        AtomicLong atomicLong = new AtomicLong();
        for(int i = 0;i < threadCount;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int j = 0;j < times;j++){
                        atomicLong.incrementAndGet();
                    }
                    countDownLatch.countDown();
                }
            },"my-thread" + i).start();
        }
        countDownLatch.await();
    }

    static void testLongAdder(int threadCount,int times) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        LongAdder longAdder = new LongAdder();
        for(int i = 0;i < threadCount;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int j = 0;j < times;j++){
                        longAdder.add(1);
                    }
                    countDownLatch.countDown();
                }
            },"my-thread" + i).start();
        }
        countDownLatch.await();
    }
}
